//qt消息发送函数

#include "userLog.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/msg.h>
#include "msg_qt.h"

// 用于创建一个唯一的key
#define MSG_FILE "/etc/issue"

enum qt_msg_type
{
	QT_MSG_DAIJI_RUCHANG = 1,
	QT_MSG_LINSHICHE_RUCHANG,
	QT_MSG_YUEZUCHE_RUCHANG,
	QT_MSG_NO_CARID_RUCHUANG,
	QT_MSG_CHUXUCHE_RUCHANG,
	QT_MSG_LUOJIA_RUCHANG,
	QT_MSG_NO_FEE_CHUCHANG,
	QT_MSG_WITH_FEE_CHUCHANG,
	QT_MSG_NO_CARID_CHUCHANG,
	QT_MSG_SUOCHE_CHUCHANG,
	QT_MSG_LUOJIA_CHUCHANG,
	QT_MSG_DAIJI_CHUCHANG
};

typedef struct _daiji_data
{
	uint32_t number;
} __attribute__((packed)) daiji_data;

typedef struct _linshiche_data
{
	char car_id[32];
	uint8_t car_type;
} __attribute__((packed)) linshiche_data;

typedef struct _yuezuche_data
{
	char car_id[32];
	uint8_t car_type;
	uint32_t left_day;
} __attribute__((packed)) yuezuche_data;

typedef struct _chuxuche_data
{
	char car_id[32];
	uint8_t car_type;
	uint32_t left_money;
} __attribute__((packed)) chuxuche_data;

typedef struct _no_fee_data
{
	char car_id[32];
	uint8_t car_type;
	uint8_t hour;
	uint8_t minute;
} __attribute__((packed)) no_fee_data;

typedef struct _with_fee_data
{
	char car_id[32];
	uint8_t car_type;
	uint8_t hour;
	uint8_t minute;
	uint32_t money;
} __attribute__((packed)) with_fee_data;

// 消息结构
typedef struct _msg_form
{
	long mtype;
	char mtext[256];
} msg_form;

static int msqid;
#define QT_MSG_TYPE (0x5a5a)

static int send_msg_2_qt(uint32_t msg_type, void *msg_data, int msg_len);

/**********待机入场***********
number：是停车场剩余的车位数量

******************************/
int send_daiji_ruchang(int number)
{
	daiji_data data = {number};
	return send_msg_2_qt(QT_MSG_DAIJI_RUCHANG, (void *)&data, sizeof(data));
}

/**********临时车入场***********
car_id：是车牌
car_type：是车的类型

******************************/
int send_linshiche_ruchang(const char *car_id, uint8_t car_type)
{
	linshiche_data data; 
	memset(&data, 0, sizeof(data));
	data.car_type = car_type;
	strncpy(data.car_id, car_id, 31);
	return send_msg_2_qt(QT_MSG_LINSHICHE_RUCHANG, (void *)&data, sizeof(data));
}

/**********月租车入场***********
car_id：是车牌
car_type：是车的类型
left_day：月租车剩余天数

******************************/
int send_yuezuche_ruchang(const char *car_id, uint8_t car_type, uint32_t left_day)
{
	yuezuche_data data;

	memset(&data, 0, sizeof(data));
	data.car_type = car_type;
	strncpy(data.car_id, car_id, 31);

	return send_msg_2_qt(QT_MSG_YUEZUCHE_RUCHANG, (void *)&data, sizeof(data));
}

/**********无牌车入场***********
参数:无

******************************/
int send_wupaiche_ruchang()
{
	return send_msg_2_qt(QT_MSG_NO_CARID_RUCHUANG, NULL, 0);
}

/**********储蓄车入场***********
car_id：是车牌
car_type：是车的类型
left_money：月租车剩余天数

******************************/
int send_chuxuche_ruchang(const char *car_id, uint8_t car_type, uint32_t left_money)
{
	chuxuche_data data;

	memset(&data, 0, sizeof(data));
	data.car_type = car_type;
	strncpy(data.car_id, car_id, 31);
	data.left_money = left_money;

	return send_msg_2_qt(QT_MSG_CHUXUCHE_RUCHANG, (void *)&data, sizeof(data));
}

/**********杆长时间不下，到时间后落闸***********
参数:无

******************************/
int send_laojia_ruchang()
{
	return send_msg_2_qt(QT_MSG_LUOJIA_RUCHANG, NULL, 0);
}

/**********不收费车辆出场***********
car_id：是车牌
car_type：是车的类型
hour：车停放时间小时
minute:车停放时间分钟

******************************/
int send_no_fee_chuchang(const char *car_id, uint8_t car_type, uint8_t hour, uint8_t minute)
{
	no_fee_data data;
	memset(&data, 0, sizeof(data));
	data.car_type = car_type;
	strncpy(data.car_id, car_id, 31);
	data.hour = hour;
	data.minute = minute;

	return send_msg_2_qt(QT_MSG_NO_FEE_CHUCHANG, (void *)&data, sizeof(data));
}

/**********收费车辆出场***********
car_id：是车牌
car_type：是车的类型
hour：车停放时间小时
minute:车停放时间分钟

******************************/
int send_with_fee_chuchang(const char *car_id, uint8_t car_type, uint8_t hour, uint8_t minute, uint32_t money)
{
	with_fee_data data;
	memset(&data, 0, sizeof(data));
	data.car_type = car_type;
	strncpy(data.car_id, car_id, 31);
	data.hour = hour;
	data.money = money;
	data.minute = minute;

	return send_msg_2_qt(QT_MSG_WITH_FEE_CHUCHANG, (void *)&data, sizeof(data));
}

/**********无牌车出场***********
参数:无

******************************/
int send_no_carId_chuchang()
{
	return send_msg_2_qt(QT_MSG_NO_CARID_CHUCHANG, NULL, 0);
}

/**********出场提示锁车***********
参数:无

******************************/
int send_suoche_chuchang()
{
	return send_msg_2_qt(QT_MSG_SUOCHE_CHUCHANG, NULL, 0);
}

/**********杆长时间不下，到时间后落闸***********
参数:无

******************************/
int send_luojia_chuchang()
{
	return send_msg_2_qt(QT_MSG_LUOJIA_CHUCHANG, NULL, 0);
}

/**********待机状态***********
参数:无

******************************/
int send_daiji_chuchang()
{
	return send_msg_2_qt(QT_MSG_DAIJI_CHUCHANG, NULL, 0);
}

static int send_msg_2_qt(uint32_t msg_type, void *msg_data, int msg_len)
{
	msg_form msg;
	memset(&msg, 0, sizeof(msg_form));
	uint32_t offset = sizeof(msg_type);

	memcpy(&msg.mtext[0], (void *)&msg_type, offset);
	if (msg_data != NULL)
	{
		memcpy(&msg.mtext[offset], msg_data, msg_len);
	}
	msg.mtype = QT_MSG_TYPE;
	int ret = msgsnd(msqid, &msg, msg_len + offset, 0);
	//LOG_INFO("send_msg_2_qt msg_type:%d %s", msg_type, ret == 0 ? "success" : "fail");
	return ret == 0 ? 0 : (-1);
}

int qt_msg_init()
{
	int msqid;
	key_t key;

	// 获取key值
	if ((key = ftok(MSG_FILE, 'z')) < 0)
	{
		perror("ftok error");
		exit(1);
	}

	// 打印key值
	LOG_INFO("Message Queue - Client key is: %d.\n", key);

	// 打开消息队列
	if ((msqid = msgget(key, IPC_CREAT | 0777)) == -1)
	{
		perror("msgget error");
		exit(1);
	}

	return 0;
}
